package com.catazy.mvvmlib.util

import android.content.Context
import android.net.ConnectivityManager
import android.net.NetworkCapabilities
import android.os.Build
import android.telephony.TelephonyManager
import com.blankj.utilcode.util.LogUtils
import com.catazy.mvvmlib.ext.isAbsUrl
import com.catazy.mvvmlib.ext.isDataUrl
import okhttp3.Call
import okhttp3.Callback
import okhttp3.OkHttpClient
import okhttp3.Request
import okhttp3.Response
import java.io.IOException
import java.net.Inet4Address
import java.net.InetAddress
import java.net.NetworkInterface
import java.net.URL
import java.util.Enumeration

/**
 * 作者: Tao
 * 日期: 2023/10/31
 * 时间: 11:01
 * 描述: 网络工具类
 */
object NetworkUtil {

    fun test(){
        val build = OkHttpClient.Builder().build()
        val request = Request.Builder().url("https:").build()
        build.newCall(request).execute() //同步调用
        build.newCall(request).enqueue(object : Callback{
            override fun onFailure(call: Call, e: IOException) {
                TODO("Not yet implemented")
            }

            override fun onResponse(call: Call, response: Response) {
                TODO("Not yet implemented")
            }

        }) //异步调用

    }

    /**
     * 网络是否可用
     * @param context Context
     * @return Boolean true 可用 | false 不可用
     */
    fun isAvailable(context: Context): Boolean {
        val cm =
            context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        return if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val nc = cm.getNetworkCapabilities(cm.activeNetwork)
            nc?.hasCapability(NetworkCapabilities.NET_CAPABILITY_INTERNET) == true
        } else {
            cm.activeNetworkInfo?.isAvailable == true
        }
    }

    /**
     * 网络连接是否可用
     *
     * @param context [Context]
     * @return true if available, false if not
     */
    fun isNetworkAvailable(context: Context): Boolean {
        val cm =
            context.applicationContext.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
                ?: return false
        val info = cm.activeNetworkInfo
        if (info != null && info.isConnected && info.isAvailable) {
            // 检查IP地址
            val ip: String? = getIPAddress()
            return ip != null
        }
        return false
    }

    fun getIPAddress(): String? {
        try {
            val en: Enumeration<*>? = NetworkInterface.getNetworkInterfaces()
            while (en != null && en.hasMoreElements()) {
                val ni = en.nextElement() as NetworkInterface
                val ipAddress: Enumeration<*>? = ni.inetAddresses
                while (ipAddress != null && ipAddress.hasMoreElements()) {
                    val inetAddress = ipAddress.nextElement() as InetAddress
                    if (!inetAddress.isLoopbackAddress && inetAddress is Inet4Address) {
                        return inetAddress.getHostAddress()
                    }
                }
            }
        } catch (e: java.lang.Exception) {
            e.printStackTrace()
        }
        return null
    }

    /**
     * 获取网络类型
     * @param context Context
     * @return NetworkType 网络类型
     */
    fun getNetworkType(context: Context): NetworkType {
        val cm = context.getSystemService(Context.CONNECTIVITY_SERVICE) as ConnectivityManager
        @Suppress("DEPRECATION") val isWiFi = if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.M) {
            val networkCapabilities = cm.getNetworkCapabilities(cm.activeNetwork)
            networkCapabilities?.hasTransport(NetworkCapabilities.TRANSPORT_WIFI) == true
        } else {
            cm.activeNetworkInfo?.type == ConnectivityManager.TYPE_WIFI
        }
        if (isWiFi) {
            return NetworkType.NETWORK_WIFI
        }

        val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        return when (tm.networkType) {
            TelephonyManager.NETWORK_TYPE_GPRS,
            TelephonyManager.NETWORK_TYPE_GSM,
            TelephonyManager.NETWORK_TYPE_EDGE,
            TelephonyManager.NETWORK_TYPE_CDMA,
            TelephonyManager.NETWORK_TYPE_1xRTT,
            TelephonyManager.NETWORK_TYPE_IDEN -> NetworkType.NETWORK_2G

            TelephonyManager.NETWORK_TYPE_UMTS,
            TelephonyManager.NETWORK_TYPE_EVDO_0,
            TelephonyManager.NETWORK_TYPE_EVDO_A,
            TelephonyManager.NETWORK_TYPE_HSDPA,
            TelephonyManager.NETWORK_TYPE_HSUPA,
            TelephonyManager.NETWORK_TYPE_HSPA,
            TelephonyManager.NETWORK_TYPE_EVDO_B,
            TelephonyManager.NETWORK_TYPE_EHRPD,
            TelephonyManager.NETWORK_TYPE_HSPAP,
            TelephonyManager.NETWORK_TYPE_TD_SCDMA -> NetworkType.NETWORK_3G

            TelephonyManager.NETWORK_TYPE_LTE -> NetworkType.NETWORK_4G

            TelephonyManager.NETWORK_TYPE_IWLAN -> NetworkType.NETWORK_WIFI
            TelephonyManager.NETWORK_TYPE_NR -> NetworkType.NETWORK_5G

            else -> NetworkType.NETWORK_UNKNOWN
        }
    }

    /**
     * 获取运营商
     * @param context Context
     * @return string 运营商名称
     */
    fun getOperatorName(context: Context): String {
        val tm = context.getSystemService(Context.TELEPHONY_SERVICE) as TelephonyManager
        return tm.simOperatorName
    }

    /**
     * 获取绝对地址
     */
    fun getAbsoluteURL(baseURL: URL?, relativePath: String): String {
        val relativePathTrim = relativePath.trim()
        if (baseURL == null) return relativePathTrim
        if (relativePathTrim.isAbsUrl()) return relativePathTrim
        if (relativePathTrim.isDataUrl()) return relativePathTrim
        if (relativePathTrim.startsWith("javascript")) return ""
        var relativeUrl = relativePathTrim
        try {
            val parseUrl = URL(baseURL, relativePath)
            relativeUrl = parseUrl.toString()
            return relativeUrl
        } catch (e: Exception) {
            LogUtils.d("网址拼接出错\n${e.localizedMessage}", e)
        }
        return relativeUrl
    }

    /**
     * 获取绝对地址
     */
    fun getAbsoluteURL(baseURL: String?, relativePath: String): String {
        if (baseURL.isNullOrEmpty()) return relativePath.trim()
        var absoluteUrl: URL? = null
        try {
            absoluteUrl = URL(baseURL.substringBefore(","))
        } catch (e: Exception) {
            e.printStackTrace()
        }
        return getAbsoluteURL(absoluteUrl, relativePath)
    }
}

/**
 * 网路类型枚举
 */
enum class NetworkType {

    /**
     * 未知网络
     */
    NETWORK_UNKNOWN,

    /**
     * wifi
     */
    NETWORK_WIFI,

    /**
     * 2G
     */
    NETWORK_2G,

    /**
     * 3G
     */
    NETWORK_3G,

    /**
     * 4G
     */
    NETWORK_4G,

    /**
     * 5G
     */
    NETWORK_5G
}